package shell;

import java.io.*;

/**
 * @author dingnate
 */
public class ShellProcess extends Process {
    private static String[] cmd = {"/bin/bash"};
    //    private static String[] cmd = {"cmd"};
    private final Process process;
    private final TerminalReader terminalReader;

    public Process getProcess() {
        return process;
    }

    public String getResponse() {
        return terminalReader.getResponse();
    }


    public ShellProcess() throws IOException {
        process = new ProcessBuilder().redirectErrorStream(true).command(cmd).start();
        terminalReader = new TerminalReader(process);
        terminalReader.start();
    }

    @Override
    public OutputStream getOutputStream() {
        return process.getOutputStream();
    }

    @Override
    public InputStream getInputStream() {
        return process.getInputStream();
    }

    @Override
    public InputStream getErrorStream() {
        return process.getErrorStream();
    }

    @Override
    public int waitFor() throws InterruptedException {
        return process.waitFor();
    }

    @Override
    public int exitValue() {
        return process.exitValue();
    }

    @Override
    public void destroy() {
        terminalReader.interrupt();
        process.destroy();
    }

    private static class TerminalReader extends Thread {
        private final BufferedReader br;
        private StringBuilder responseBuilder = new StringBuilder();
        private static final int MAX_LENGTH = 1024;
        private boolean full = false;

        public TerminalReader(Process process) {
            this.br = new BufferedReader(new InputStreamReader(process.getInputStream()));
        }

        @Override
        public void run() {
            try {
                String s;
                while ((s = br.readLine()) != null) {
                    if (responseBuilder.length() > MAX_LENGTH) {
                        if (!full) {
                            full = true;
                            responseBuilder.append("...\n");
                        }
                    } else {
                        responseBuilder.append(s).append("\n");
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("TerminalReader die.");
        }

        public String getResponse() {
            try {
                if (responseBuilder.length() == 0) {
                    sleep(200);
                }
                int length = responseBuilder.length();
                if (length == 0) {
                    return "\n";
                }

                while (length != responseBuilder.length()) {
                    sleep(50);
                    length = responseBuilder.length();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String response = responseBuilder.toString();
            responseBuilder.delete(0, responseBuilder.length());
            full = false;
            return response;
        }
    }
}